package com.disk.service.impl;

import com.disk.domain.User;
import com.disk.domain.UserLoginDetail;
import com.disk.handleResult.DiskMessage;
import com.disk.handleResult.Result;
import com.disk.service.LoginService;
import com.disk.utils.JwtUtil;
import com.disk.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;


@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    /**
     * 在接口中我们通过AuthenticationManager的authenticate方法来进行用户认证,
     * 所以需要在SecurityConfig中配置把AuthenticationManager注入容器。
     *
     * 认证成功的话要生成一个jwt，放入响应中返回。
     * 并且为了让用户下回请求时能通过jwt识别出具体的是哪个用户，我们需要把用户信息存入redis，可以把用户id作为key。
     * @param user
     * @return
     */
    @Override
    public Result login(User user) {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=
                new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());

        // TODO 使用AuthenticationManager的 authenticate方法调用
        //  我们实现的UserDetailsService中的loadUserByUsername方法进行验证
        Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        if(authentication==null)
        {
            throw new RuntimeException(DiskMessage.LOGIN_FAILD);
        }

        //使用userid生成token
        UserLoginDetail userLoginDetail = (UserLoginDetail) authentication.getPrincipal();
        String userId = userLoginDetail.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(userId);

//        authenticate存入redis
        redisCache.setCacheObject("login:"+userId,userLoginDetail);

        return new Result(true, DiskMessage.LOGIN_SUCCESS,jwt);
    }

    @Override
    public Result logout() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserLoginDetail userLoginDetail = (UserLoginDetail) authentication.getPrincipal();
        Integer id = userLoginDetail.getUser().getId();
        redisCache.deleteObject("login:"+id);
        return new Result(true,"退出成功");
    }
}
